package controller

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntityManager"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/httpserver"
	"go-fox-edge-kernel-manager/utils/PageUtils"
	"golang.org/x/crypto/bcrypt"
	"strconv"
	"strings"
)

type userManageController struct {
}

func (e *userManageController) init() {
	httpserver.Server.POST("/user/entities", e.selectEntityList)
	httpserver.Server.POST("/user/page", e.selectPageList)
	httpserver.Server.GET("/user/entity", e.queryEntity)
	httpserver.Server.POST("/user/entity", e.insertEntity)
	httpserver.Server.PUT("/user/entity", e.updateEntity)
	httpserver.Server.DELETE("/user/entity", e.deleteEntity)

	httpserver.Server.GET("/user/userinfo", e.getUserInfo)
	httpserver.Server.PUT("/user/password", e.updatePassword)

	httpserver.Server.DELETE("/user/entities", e.deleteEntityList)
}

func (e *userManageController) selectEntityList(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	return e.selectList(context, body, false)
}

func (e *userManageController) selectPageList(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	return e.selectList(context, body, true)
}

func (e *userManageController) selectList(context httpserver.Context, body map[string]interface{}, isPage bool) (interface{}, error) {
	entityList := commEntityManager.FindEntityList(edgeEntity.Type.UserEntity.Type(), func(value commEntity.IEntity) bool {
		entity := value.(*edgeEntity.UserEntity)

		result := true

		if Map.Has(body, "username") {
			result = result && strings.Count(entity.UserName, body["username"].(string)) > 0
		}
		if Map.Has(body, "role") {
			result = result && entity.Role == body["role"]
		}
		if Map.Has(body, "permission") {
			result = result && entity.Permission == body["permission"]
		}
		if Map.Has(body, "menu") {
			result = result && entity.Menu == body["menu"]
		}

		return result
	})

	// 获得分页数据
	if isPage {
		return PageUtils.GetPageList(entityList, body), nil
	} else {
		return commEntity.BuildMapList(entityList), nil
	}
}

func (e *userManageController) queryEntity(context httpserver.Context) (interface{}, error) {
	username := context.Query("username")
	if username == "" {
		return nil, errors.New("输入的username为null")
	}

	find := edgeEntity.Type.UserEntity.Instance()
	find.UserName = username
	exist, err := commEntityManager.GetEntityByServiceKey(edgeEntity.Type.UserEntity.Type(), find.MakeServiceKey())
	if exist == nil || err != nil {
		return nil, errors.New("实体不存在")
	}

	return commEntity.BuildMap(exist), nil
}

func (e *userManageController) getUserInfo(context httpserver.Context) (interface{}, error) {
	username := context.Query("username")
	if username == "" {
		return nil, errors.New("输入的username为null")
	}

	findUser := edgeEntity.Type.UserEntity.Instance()
	findUser.UserName = username
	existUser, err := commEntityManager.GetEntityByServiceKey(edgeEntity.Type.UserEntity.Type(), findUser.MakeServiceKey())
	if existUser == nil || err != nil {
		return nil, errors.New("实体不存在")
	}

	findRole := edgeEntity.Type.UserRoleEntity.Instance()
	findRole.Name = existUser.(*edgeEntity.UserEntity).Role
	existRole, err := commEntityManager.GetEntityByServiceKey(edgeEntity.Type.UserRoleEntity.Type(), findRole.MakeServiceKey())
	if existRole == nil || err != nil {
		return nil, errors.New("实体不存在")
	}

	findPerm := edgeEntity.Type.UserPermissionEntity.Instance()
	findPerm.Name = existUser.(*edgeEntity.UserEntity).Permission
	existPerm, err := commEntityManager.GetEntityByServiceKey(edgeEntity.Type.UserPermissionEntity.Type(), findPerm.MakeServiceKey())
	if existRole == nil || err != nil {
		return nil, errors.New("实体不存在")
	}

	result := make(map[string]interface{})
	result["nickname"] = existUser.(*edgeEntity.UserEntity).UserName
	result["roles"] = existRole.(*edgeEntity.UserRoleEntity).Params
	result["perms"] = existPerm.(*edgeEntity.UserPermissionEntity).Params

	return existUser, nil
}

func (e *userManageController) insertEntity(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	delete(body, "id")
	return e.insertOrUpdate(context, body)
}

func (e *userManageController) updateEntity(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	return e.insertOrUpdate(context, body)
}

func (e *userManageController) insertOrUpdate(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	// 提取业务参数
	username := Map.GetString(body, "username", "")
	menu := Map.GetString(body, "menu", "")
	role := Map.GetString(body, "role", "")
	permission := Map.GetString(body, "permission", "")

	// 简单校验参数
	if Method.HasEmpty(username, menu, role, permission) {
		return nil, errors.New("参数不能为空:username, menu, role, permission")
	}

	// 构造作为参数的实体
	entity := edgeEntity.Type.UserEntity.Instance()
	entity.UserName = username
	entity.Menu = menu
	entity.Role = role
	entity.Permission = permission

	// 新增/修改实体：参数不包含id为新增，包含为修改
	if !Map.Has(body, "id") {
		exist, err := commEntityManager.GetEntityByServiceKey(entity.Type(), entity.MakeServiceKey())
		if err != nil {
			return nil, err
		}
		if exist != nil {
			return nil, errors.New("实体已存在")
		}

		// 生成一个默认密码
		pwd, err := bcrypt.GenerateFromPassword([]byte("12345678"), bcrypt.DefaultCost)
		if err != nil {
			return nil, errors.New("生成默认密码失败")
		}
		entity.PassWord = string(pwd)

		entity.UserType = "user"
		err = commEntityManager.InsertEntity(entity)
		if err != nil {
			return nil, err
		}

		return nil, nil
	} else {
		id := Map.GetInt64(body, "id", 0)

		exist := commEntityManager.GetEntityById(entity.Type(), id)
		if exist == nil {
			return nil, errors.New("实体不存在")
		}

		// 修改数据
		entity.BaseEntity.Id = id
		entity.GetBaseEntity().CreateTime = exist.GetBaseEntity().CreateTime
		entity.GetBaseEntity().UpdateTime = exist.GetBaseEntity().UpdateTime
		entity.PassWord = exist.(*edgeEntity.UserEntity).PassWord
		entity.UserType = exist.(*edgeEntity.UserEntity).UserType
		return nil, commEntityManager.UpdateEntity(entity)
	}
}

func (e *userManageController) deleteEntity(context httpserver.Context) (interface{}, error) {
	str := context.Query("id")
	if str == "" {
		return nil, errors.New("输入的id为null")
	}

	id, err := strconv.ParseInt(str, 10, 64)
	if err != nil {
		return nil, err
	}

	exist := commEntityManager.GetEntityById(edgeEntity.Type.UserEntity.Type(), id)
	if exist == nil {
		return nil, errors.New("实体不存在")
	}

	err = commEntityManager.DeleteEntity(exist)
	if err != nil {
		return nil, err
	}

	return commEntity.BuildMap(exist), nil
}

func (e *userManageController) deleteEntityList(context httpserver.Context) (interface{}, error) {
	ids := context.Query("ids")

	idList := strings.Split(ids, ",")
	for _, str := range idList {
		if str == "" {
			continue
		}
		id, err := strconv.ParseInt(str, 10, 64)
		if err != nil {
			return nil, err
		}

		exist := commEntityManager.GetEntityById(edgeEntity.Type.UserEntity.Type(), id)
		if exist == nil {
			return nil, errors.New("实体不存在")
		}

		err = commEntityManager.DeleteEntity(exist)
		if err != nil {
			return nil, err
		}
	}

	return nil, nil
}

func (e *userManageController) updatePassword(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	// 提取业务参数
	username := Map.GetString(body, "username", "")
	oldPassword := Map.GetString(body, "oldPassword", "")
	newPassword := Map.GetString(body, "newPassword", "")

	// 简单校验参数
	if Method.HasEmpty(username, oldPassword, newPassword) {
		return nil, errors.New("参数不能为空: username, oldPassword, newPassword")
	}

	// 查询存在的用户
	find := edgeEntity.Type.UserEntity.Instance()
	find.UserName = username
	exist, err := commEntityManager.GetEntityByServiceKey(find.Type(), find.MakeServiceKey())
	if err != nil {
		return nil, err
	}
	if exist == nil {
		return nil, errors.New("不存在该用户")
	}

	// 验证：密码是否正确
	existEntity := exist.(*edgeEntity.UserEntity)
	err = bcrypt.CompareHashAndPassword([]byte(existEntity.PassWord), []byte(oldPassword))
	if err != nil {
		return nil, errors.New("密码验证不通过")
	}

	// 生成一个默认密码
	pwd, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
	if err != nil {
		return nil, errors.New("生成默认密码失败")
	}
	existEntity.PassWord = string(pwd)

	return nil, commEntityManager.UpdateEntity(existEntity)
}
